#pragma once

#include <algorithm/shared/utils/GenericVectorMath.h>
#include <utils/config.h>

inline HOT_FUNCTION __host__ __device__ auto operator-(const int2& a) -> int2
{
    return solar::internal::vector::negate(a);
}

inline HOT_FUNCTION __host__ __device__ auto operator+(const int2& a, const int2& b) -> int2
{
    return solar::internal::vector::plus(a, b);
}

inline HOT_FUNCTION __host__ __device__ auto operator+(const int2& a, const int& b) -> int2
{
    return solar::internal::vector::plus(a, b);
}

inline HOT_FUNCTION __host__ __device__ auto operator+(const int& b, const int2& a) -> int2
{
    return solar::internal::vector::plus(a, b);
}

inline HOT_FUNCTION __host__ __device__ void operator+=(int2& a, const int2& b)
{
    solar::internal::vector::plusSelf(a, b);
}

inline HOT_FUNCTION __host__ __device__ auto operator-(const int2& a, const int2& b) -> int2
{
    return solar::internal::vector::minus(a, b);
}

inline HOT_FUNCTION __host__ __device__ auto operator-(const int2& a, const int& b) -> int2
{
    return solar::internal::vector::minus(a, b);
}

inline HOT_FUNCTION __host__ __device__ auto operator-(const int& b, const int2& a) -> int2
{
    return solar::internal::vector::minus(a, b);
}

inline HOT_FUNCTION __host__ __device__ void operator-=(int2& a, const int2& b)
{
    solar::internal::vector::minusSelf(a, b);
}

inline HOT_FUNCTION __host__ __device__ auto operator*(const int2& a, const int2& b) -> int2
{
    return solar::internal::vector::multiply(a, b);
}

inline HOT_FUNCTION __host__ __device__ auto operator*(const int2& a, const int& s) -> int2
{
    return solar::internal::vector::multiply(a, s);
}

inline HOT_FUNCTION __host__ __device__ auto operator*(const int& s, const int2& a) -> int2
{
    return solar::internal::vector::multiply(a, s);
}

inline HOT_FUNCTION __host__ __device__ void operator*=(int2&& a, const int& s)
{
    solar::internal::vector::multiplySelf(a, s);
}

inline HOT_FUNCTION __device__ __host__ auto lerp(const int2& a, const int2& b,
                                                  const int& t) -> int2
{
    return solar::internal::vector::lerp(a, b, t);
}

inline HOT_FUNCTION __device__ __host__ auto clamp(const int2& v, const int& a,
                                                   const int& b) -> int2
{
    return solar::internal::vector::clamp(v, a, b);
}

inline HOT_FUNCTION __device__ __host__ auto clamp(const int2& v, const int2& a,
                                                   const int2& b) -> int2
{
    return solar::internal::vector::clamp(v, a, b);
}

inline HOT_FUNCTION __host__ __device__ auto dot(const int2& a, const int2& b) -> int
{
    return solar::internal::vector::dot(a, b);
}

inline HOT_FUNCTION __host__ __device__ auto length(const int2& v) -> float
{
    return solar::internal::vector::length(v);
}

inline HOT_FUNCTION __host__ __device__ auto rlength(const int2& v) -> float
{
    return solar::internal::vector::rlength(v);
}

inline HOT_FUNCTION __host__ __device__ auto normalize(const int2& v) -> int2
{
    return solar::internal::vector::normalize(v);
}

inline HOT_FUNCTION __host__ __device__ auto floor(const int2& v) -> int2
{
    return solar::internal::vector::floor(v);
}

inline HOT_FUNCTION __host__ __device__ auto reflect(const int2& i, const int2& n) -> int2
{
    return solar::internal::vector::reflect(i, n);
}

inline HOT_FUNCTION __host__ __device__ auto abs(const int2& v) -> int2
{
    return solar::internal::vector::abs(v);
}

inline HOT_FUNCTION __host__ __device__ auto max(const int2& a, const int2& b) -> int2
{
    return solar::internal::vector::max(a, b);
}

inline HOT_FUNCTION __host__ __device__ auto min(const int2& a, const int2& b) -> int2
{
    return solar::internal::vector::min(a, b);
}
